/**
 * Copyright 2009 University of Washington This code is released under the GPL version 3 - with a copy of the license
 * included
 * 
 * @author Maya Hao Li
 */
package seedpod.model;

/*
 * This class binds a relationship between an object's attribute value, to a method which transforms the value into a
 * value that can be stored in the database. UserVal->toDbVal(userVal)->DbVal toDbVal are classes of methods that will
 * transform the value ToDbVal also can implement how a user entry should interact with other entries in the object, and
 * how the values should be stored. Handle multi-media data here. User value validation should be done before this step.
 * UserView<- toUiVal(dbVal)<-DbVal in this case, toUiVal are methods implemented in the view package
 */

import java.util.ArrayList;

import seedpod.exceptions.DataValidationException;
import seedpod.exceptions.NonNullableException;
import seedpod.exceptions.SeedpodException;
import seedpod.kb2db.SlotMap;
import seedpod.rdb.PersistenceDO;

public class AVPair {
	protected SeedpodDO _objectInstance;
	protected SlotMap _attribute;
	protected ArrayList<Object> _values;
	protected DataValidationException _validationError = null;

	public AVPair(SeedpodDO obj, SlotMap att) {
		_objectInstance = obj;
		_attribute = att;
		_values = new ArrayList<Object>();
	}

	// initialize a binder with multi-value
	public AVPair(SeedpodDO obj, SlotMap att, ArrayList<Object> values) {
		_objectInstance = obj;
		_attribute = att;
		_values = values;
	}

	public AVPair(SeedpodDO obj, SlotMap att, Object value) {
		_objectInstance = obj;
		_attribute = att;
		_values = new ArrayList<Object>();
		_values.add( value );
	}

	public void addValue( Object value ) {
		_values.add( value );
	}

	public String genRefId() {
		Integer oid = _objectInstance.getOid();
		if ( oid == null ) oid = PersistenceDO.UNKNOWN_OID; // TODO needs to change for batch edit of new objects.

		return _attribute.getName() + "(" + oid + ")";
	}

	public SlotMap getAttribute() {
		return _attribute;
	}

	public DataValidationException getError() {
		return _validationError;
	}

	public SeedpodDO getSeedpodDO() {
		return _objectInstance;
	}

	public String getStringValue() {
		Object value = getValue();
		if ( value == null || value.toString().equalsIgnoreCase( "null" ) )
			return "";
		else return value.toString();
	}

	public Object getValue() {
		return _values != null && _values.size() > 0 ? _values.get( 0 ) : null;
	}

	/**
	 * This sets the database value. Convert from user entry to the right
	 * 
	 * @param value
	 * @throws SeedpodException
	 * @throws NullSlotMapException
	 */
	public void setValue( Object userEntry ) {
		_values.add( 0, userEntry );
	}

	public void setValues( ArrayList<Object> userEntries ) {
		_values = userEntries;
	}

	/**
	 * Generic value validater that returns false for values that are null but shouldn't be. One can implement other
	 * AVPair classes that override this function
	 */
	public boolean validate() throws DataValidationException {
		if ( !_attribute.isNullable() )
			if ( _values == null || _values.size() == 0 ) throw new NonNullableException( _attribute.getName() );
		return true;
	}

}